package com.dzwww.recommend.rule.controller;

import com.dzwww.recommend.rule.common.api.ApiResult;
import com.dzwww.recommend.rule.common.po.RuleConfig;
import com.dzwww.recommend.rule.service.common.RuleConfigService;
import com.dzwww.recommend.rule.service.common.ShuWenInterfaceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import lombok.extern.slf4j.Slf4j;

import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.ws.rs.core.MediaType;

/**
 * 推荐api(旧版)
 * @author Administrator
 * 2019年7月19日
 */
@RestSchema(schemaId = "recommendApi")
@RequestMapping(path = "/recommend/api", produces = MediaType.APPLICATION_JSON)
@Slf4j
public class RecommendApiController  {
	
	private static int RECOMMEND_BASE_NUM = 20;
	private static int RELATIVE_BASE_NUM = 5;
	private static int HOT_BASE_NUM = 5;
	
	private static int RECOMMEND_PULL_NUM = 20;
	private static int RELATIVE_PULL_NUM = 5;
	private static int HOT_PULL_NUM = 5;
	
	@Resource
    RuleConfigService ruleConfigService;


	/**
	 * 个性化推荐
	 * @param userId
	 * @param size
	 * @return
	 */
    @GetMapping("personal")
    public ApiResult recommend(@RequestParam(value = "userId",required = true) String userId, 
    		@RequestParam(value = "size",required = false) Integer size){
    	
    	int count = RECOMMEND_BASE_NUM;
    	if(size != null){
    		count = size.intValue();
    	}
    	//获取智云推荐的结果
    	List<String> shuwenList = getShuWenRecommend(userId, count);
    	if(shuwenList.size() == 0){
    		return ApiResult.fail("","从智云推荐没有获取到数据!");
    	}
		
    	//获取推荐规则配置的过滤新闻ID
    	List<String> ruleList = getRuleList();
    	
    	//整理推荐列表
		shuwenList.removeAll(ruleList);
		if(shuwenList.size() < count){
			recurseRecommend(userId, shuwenList, ruleList, count);
		}
        return ApiResult.succeed(shuwenList);
    }
    
    /**
	 * 相关新闻推荐
	 * 注意：智云推荐接口对某条新闻的相关新闻返回结果是不变的
	 * @param userId
	 * @param newsId
	 * @param size
	 * @return
	 */
    @GetMapping("relative")
    public ApiResult relative(@RequestParam(value = "userId",required = true) String userId, 
    		@RequestParam(value = "newsId",required = true) String newsId, 
    		@RequestParam(value = "size",required = false) Integer size){
    	
    	int count = RELATIVE_BASE_NUM;
    	if(size != null){
    		count = size.intValue();
    	}
    	//获取智云推荐的结果
    	List<String> shuwenList = getShuWenRelative(userId, newsId, count);
    	if(shuwenList.size() == 0){
    		return ApiResult.fail("","从智云推荐没有获取到数据!");
    	}
		
    	//获取推荐规则配置的过滤新闻ID
    	List<String> ruleList = getRuleList();
    	
    	//整理推荐列表
		shuwenList.removeAll(ruleList);
		//智云推荐接口对某条新闻的相关新闻返回结果是不变的，所以不用递归再填充了
		/*
		if(shuwenList.size() < count){
			recurseRelative(userId, newsId, shuwenList, ruleList, count);
		}
		*/
        return ApiResult.succeed(shuwenList);
    }
    
    /**
	 * 热点推荐
	 * @param userId
	 * @param size
	 * @return
	 */
    @GetMapping("hot")
    public ApiResult hot(@RequestParam(value = "userId",required = true) String userId, 
    		@RequestParam(value = "size",required = false) Integer size){
    	
    	int count = HOT_BASE_NUM;
    	if(size != null){
    		count = size.intValue();
    	}
    	//获取智云推荐的结果
    	List<String> shuwenList = getShuWenHot(userId, count);
    	if(shuwenList.size() == 0){
    		return ApiResult.fail("","从智云推荐没有获取到数据!");
    	}
		
    	//获取推荐规则配置的过滤新闻ID
    	List<String> ruleList = getRuleList();
    	
    	//整理推荐列表
		shuwenList.removeAll(ruleList);
		if(shuwenList.size() < count){
			recurseHot(userId, shuwenList, ruleList, count);
		}
        return ApiResult.succeed(shuwenList);
    }
    
    private List<String> getShuWenRecommend(String userId, int count){
    	String result = ShuWenInterfaceImpl.recommend(userId, count);
    	return jsonStr2List(result);
    }
    
    private List<String> getShuWenRelative(String userId, String newsId, int count){
    	String result = ShuWenInterfaceImpl.relative(userId, newsId, count);
    	return jsonStr2List(result);
    }
    
    private List<String> getShuWenHot(String userId, int count){
    	String result = ShuWenInterfaceImpl.hot(userId, count);
    	return jsonStr2List(result);
    }
    
    private List<String> jsonStr2List(String result){
    	List<String> recommendList = new ArrayList<String>();
    	Gson gson = new Gson();
    	JsonObject jo = gson.fromJson(result, JsonObject.class);
    	JsonObject jt = jo.getAsJsonObject("data");
		JsonArray ja = jt.getAsJsonArray("newsIds");
		Iterator<JsonElement> iter = ja.iterator();
    	while(iter.hasNext()){
    		JsonElement je = iter.next();
    		String filterId = je.getAsString();
    		recommendList.add(filterId);
    	}
    	return recommendList;
    }
    
    private List<String> getRuleList(){
    	RuleConfig ruleConfig = new RuleConfig();
    	ruleConfig.setFilterword("newsId");
    	ruleConfig = ruleConfigService.getBy(ruleConfig);
    	log.info("---过滤新闻ID的规则:---" + ruleConfig.toString());
    	String newsIds = ruleConfig.getFiltertext();
    	String[] news = newsIds.split(",");
    	List<String> ruleList = Arrays.asList(news);
    	return ruleList;
    }
    
    private void recurseRecommend(String userId, List<String> shuwenList, List<String> ruleList, int count){
    	//再从智云推荐拉取数据
		List<String> continueList = getShuWenRecommend(userId, RECOMMEND_PULL_NUM);
		continueList.removeAll(ruleList);
		int num = shuwenList.size() + continueList.size();
		if(num == count){
			shuwenList.addAll(continueList);
		}
		if(num < count){
			//递归
			shuwenList.addAll(continueList);
			recurseRecommend(userId, shuwenList, ruleList, count);
		}
		if(num > count){
			int sub = count - shuwenList.size();
			continueList = continueList.subList(0, sub);
			shuwenList.addAll(continueList);
		}
    }
    
    /*
    private void recurseRelative(String userId, String newsId, List<String> shuwenList, List<String> ruleList, int count){
    	//再从智云推荐拉取数据
		List<String> continueList = getShuWenRelative(userId, newsId, RELATIVE_PULL_NUM);
		continueList.removeAll(ruleList);
		int num = shuwenList.size() + continueList.size();
		if(num == count){
			shuwenList.addAll(continueList);
		}
		if(num < count){
			//递归
			shuwenList.addAll(continueList);
			recurseRelative(userId, newsId, shuwenList, ruleList, count);
		}
		if(num > count){
			int sub = count - shuwenList.size();
			continueList = continueList.subList(0, sub);
			shuwenList.addAll(continueList);
		}
    }
    */
    
    private void recurseHot(String userId, List<String> shuwenList, List<String> ruleList, int count){
    	//再从智云推荐拉取数据
		List<String> continueList = getShuWenHot(userId, HOT_PULL_NUM);
		continueList.removeAll(ruleList);
		int num = shuwenList.size() + continueList.size();
		if(num == count){
			shuwenList.addAll(continueList);
		}
		if(num < count){
			//递归
			shuwenList.addAll(continueList);
			recurseHot(userId, shuwenList, ruleList, count);
		}
		if(num > count){
			int sub = count - shuwenList.size();
			continueList = continueList.subList(0, sub);
			shuwenList.addAll(continueList);
		}
    }
    
}